﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BlogPlat.Controllers;
using BlogPlat.Model;
using BlogPlat.Tests.Models;
using AdminPostController = BlogPlat.Areas.Admin.Controllers.PostController;
using BlogPlat.Tests.Helpers;

namespace BlogPlat.Tests.Controllers
{
    /// <summary>
    /// Summary description for PostControllerTest
    /// </summary>
    [TestClass]
    public class PostControllerTest
    {
        public PostControllerTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        // Test method for showing newest posts on blog homepage
        public void Index_With_No_Parameters_Shows_Newest_Published_Posts()
        {
            // Arrange
            var repository = new FakePostRepository();
            List<Post> posts = Mock.CreateDummyBlogPostData();
            foreach (Post p in posts)
                repository.Add(p);

            var controller = new PostController(repository);
            var adminController = new AdminPostController(repository);

            
            // Act
            var result = (ViewResult)controller.Index();

            // Assert
            CollectionAssert.AllItemsAreInstancesOfType((ICollection)result.ViewData.Model, typeof(Post));
            foreach (Post postEntry in ((List<Post>)result.ViewData.Model))
            {
                Assert.IsFalse(postEntry.IsDraft);                
            }
            Assert.AreEqual(3, ((List<Post>)result.ViewData.Model).Count);                
        }

        [TestMethod]
        public void Index_Returns_Posts_By_Year()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new PostController(repository);
            var adminController = new AdminPostController(repository);

            adminController.Create(new Post { ID = 3, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 8, FriendlyUrl = "test-1", DatePublished = new DateTime(2009, 9, 6), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 7, FriendlyUrl = "test-1", DatePublished = new DateTime(2009, 3, 8), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 4, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 4, 7), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });

            // Act
            var result = (ViewResult)controller.Index(2010, null, null);

            // Assert
            var entries = (IList<Post>)result.ViewData.Model;
            Assert.AreEqual(2, entries.Count);       
        }

        [TestMethod]
        public void Index_Returns_Posts_By_Month_Of_Year()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new PostController(repository);
            var adminController = new AdminPostController(repository);

            adminController.Create(new Post { ID = 3, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 8, FriendlyUrl = "test-1", DatePublished = new DateTime(2009, 9, 6), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 7, FriendlyUrl = "test-1", DatePublished = new DateTime(2009, 9, 8), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 4, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 9, 7), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });

            // Act
            var result = (ViewResult)controller.Index(2009, 9, null);

            // Assert
            var entries = (IList<Post>)result.ViewData.Model;
            Assert.AreEqual(2, entries.Count);
        }

        [TestMethod]
        public void Index_Returns_Posts_By_Day()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new PostController(repository);
            var adminController = new AdminPostController(repository);

            adminController.Create(new Post { ID = 3, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 8, FriendlyUrl = "test-1", DatePublished = new DateTime(2009, 9, 6), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 7, FriendlyUrl = "test-1", DatePublished = new DateTime(2009, 4, 7), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 4, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 4, 7), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });

            // Act
            var result = (ViewResult)controller.Index(2010, 4, 7);

            // Assert
            var entries = (IList<Post>)result.ViewData.Model;
            Assert.AreEqual(1, entries.Count);
        }

        [TestMethod]
        public void FriendlyUrl_Action_Returns_Posts_By_FriendlyUrl()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new PostController(repository);
            var adminController = new AdminPostController(repository);

            adminController.Create(new Post { ID = 3, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 8, FriendlyUrl = "test-3", DatePublished = new DateTime(2009, 9, 6), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 7, FriendlyUrl = "test-6", DatePublished = new DateTime(2009, 4, 7), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });
            adminController.Create(new Post { ID = 4, FriendlyUrl = "test-2", DatePublished = new DateTime(2010, 4, 7), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 });

            // Act
            var result = (ViewResult)controller.FriendlyUrl("test-2");

            // Assert
            var entries = (Post)result.ViewData.Model;            
            Assert.AreEqual("test-2", entries.FriendlyUrl);
        }
    }
}
